﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections;
using DataAccessLogic;
using System.Data.SqlClient;
using System.Web.Security;

namespace BusinessLogic
{
    public class Constituent : Table
    {
        #region Fields
        private string _firstName;
        private string _middleName;
        private string _lastName;
        private string _name;
        private string _lastNamePrefix = string.Empty;
        private bool _isOrganization = false;
        private bool _isPrimary = true;
        private Guid _primaryID;
        private bool _isActive = true;
        private Address _address = null;
        private List<Address> _addresses = null;
        private Phone _phone = null;
        private List<Phone> _phones = null;
        private Email _emailAddress = null;
        private List<Email> _emailAddresses = null;
        #endregion

        #region Methods
        public Constituent() : base() {}
        public Constituent(Guid id)
            : base(id) 
            {
                this._addresses = Address.GetAllByConstituentID(this._id);
                this._phones = Phone.GetAllByConstituentID(this._id);
                this._emailAddresses = Email.GetAllByConstituentID(this._id);

                if(this._addresses != null && 0 < this._addresses.Count)
                {
                    IEnumerable<Address> aa = this._addresses.Where(a => a.IsPrimary);

                    if(aa != null && 0 < aa.Count())
                    {
                        this._address = aa.FirstOrDefault();
                    }
                }

                if(this._phones != null && 0 < this._phones.Count)
                {
                    IEnumerable<Phone> pp = this._phones.Where(p => p.IsPrimary);

                    if (pp != null && 0 < pp.Count())
                    {
                        this._phone = pp.FirstOrDefault();
                    }
                }

                if (this._emailAddresses != null && 0 < this._emailAddresses.Count)
                {
                    IEnumerable<Email> ee = this._emailAddresses.Where(e => e.IsPrimary);

                    if (ee != null && 0 < ee.Count())
                    {
                        this._emailAddress = ee.FirstOrDefault();
                    }
                }
            }

        public override DatabaseInteractionDescriptor TableInteractionDescription()
        {
            DatabaseInteractionDescriptor desc = new DatabaseInteractionDescriptor();
            desc.GetByIDStoredProcedure = StoredProcedures.USP_CONSTITUENT_GETBYID;
            desc.CreateStoredProcedure = StoredProcedures.USP_CONSTITUENT_CREATE;
            desc.DeleteStoredProcedure = StoredProcedures.USP_CONSTITUENT_DELETE;
            desc.UpdateStoredProcedure = StoredProcedures.USP_CONSTITUENT_UPDATE;
            return desc;
        }

        public override void Create()
        {
            //this is all so very ugly
            //needs to be made 'prettier'
            List<SqlParameter> parms = new List<SqlParameter>();
            SqlParameter p = new SqlParameter();
            p.ParameterName = "@ID";
            p.DbType = System.Data.DbType.Guid;
            p.Direction = System.Data.ParameterDirection.Output;

            parms.Add(p);
            parms.Add(new SqlParameter("@FIRSTNAME", this.FirstName));
            parms.Add(new SqlParameter("@MIDDLENAME", this.MiddleName));
            parms.Add(new SqlParameter("@LASTNAME", this.LastName));
            parms.Add(new SqlParameter("@ISORGANIZATION", this.IsOrganization));
            parms.Add(new SqlParameter("@LASTNAMEPREFIX", this.LastNamePrefix));
            parms.Add(new SqlParameter("@ISPRIMARY", this.IsPrimary));
            parms.Add(new SqlParameter("@PRIMARYID", this.PrimaryID));
            parms.Add(new SqlParameter("@ISACTIVE", this.IsActive));
            parms.Add(new SqlParameter("@ASPNETDBUSERID", Membership.GetUser().ProviderUserKey.ToString()));
            base.Create(parms);

            if((this.Address != null) && (!string.IsNullOrWhiteSpace(this.Address.AddressBlock)))
            {
                parms.Clear();
                p = new SqlParameter();
                p.ParameterName = "@ID";
                p.DbType = System.Data.DbType.Guid;
                p.Direction = System.Data.ParameterDirection.Output;
                parms.Add(p);
                parms.Add(new SqlParameter("@CONSTITUENTID", this.ID));
                parms.Add(new SqlParameter("@ADDRESSBLOCK", this.Address.AddressBlock));
                parms.Add(new SqlParameter("@CITY", this.Address.City));
                parms.Add(new SqlParameter("@POSTCODE", this.Address.PostCode));
                parms.Add(new SqlParameter("@STATEID", this.Address.State.ID));
                parms.Add(new SqlParameter("@COUNTRYID", this.Address.Country.ID));
                parms.Add(new SqlParameter("@ADDRESSTYPECODEID", this.Address.AddressType.ID));
                parms.Add(new SqlParameter("@ASPNETDBUSERID", Membership.GetUser().ProviderUserKey.ToString()));
                this.Address.Create(parms);
            }

            if((this.Phone != null) && (!string.IsNullOrWhiteSpace(this.Phone.Number)))
            {
                parms.Clear();
                p = new SqlParameter();
                p.ParameterName = "@ID";
                p.DbType = System.Data.DbType.Guid;
                p.Direction = System.Data.ParameterDirection.Output;
                parms.Add(p);
                parms.Add(new SqlParameter("@CONSTITUENTID", this.ID));
                parms.Add(new SqlParameter("@PHONETYPECODEID", this.Phone.PhoneType.ID));
                parms.Add(new SqlParameter("@NUMBER", this.Phone.Number));
                parms.Add(new SqlParameter("@EXTENSION", this.Phone.Extension));
                parms.Add(new SqlParameter("@ASPNETDBUSERID", Membership.GetUser().ProviderUserKey.ToString()));
                this.Phone.Create(parms);
            }

            if((this.EmailAddress != null) && (!string.IsNullOrWhiteSpace(this.EmailAddress.EmailAddress)))
            {
                parms.Clear();
                p = new SqlParameter();
                p.ParameterName = "@ID";
                p.DbType = System.Data.DbType.Guid;
                p.Direction = System.Data.ParameterDirection.Output;
                parms.Add(p);
                parms.Add(new SqlParameter("@CONSTITUENTID", this.ID));
                parms.Add(new SqlParameter("@EMAILADDRESS", this.EmailAddress.EmailAddress));
                parms.Add(new SqlParameter("@EMAILADDRESSTYPECODEID", this.EmailAddress.EmailAddressType.ID));
                parms.Add(new SqlParameter("@ASPNETDBUSERID", Membership.GetUser().ProviderUserKey.ToString()));
                this.EmailAddress.Create(parms);            
            }
        }

        public override void Delete()
        {
            List<SqlParameter> parms = new List<SqlParameter>();
            parms.Add(new SqlParameter("@ID", this.ID));
            base.Delete(parms);
        }

        public static List<Constituent> GetActive()
        {
            return DataAccess.Constituent_DA.GetActive();
        }

        public static List<Constituent> GetAll()
        {
            return DataAccess.Constituent_DA.GetAll();
        }

        public static List<Constituent> GetActivePrimaries()
        {
            return DataAccess.Constituent_DA.GetActivePrimaries();
        }

        private void CreateName()
        {
            if (string.IsNullOrWhiteSpace(_name))
            {
                if (_isOrganization)
                {
                    if (string.IsNullOrWhiteSpace(_lastNamePrefix))
                    {
                        _name = _lastName;
                    }
                    else
                    {
                        _name = string.Concat(_lastNamePrefix, " ", _lastName);
                    }
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(_firstName))
                    {
                        _name = "";
                    }
                    else
                    {
                        _name = string.Concat(_firstName, " ");
                    }

                    if (string.IsNullOrWhiteSpace(_middleName))
                    {
                        _name = string.Concat(_name, "");
                    }
                    else
                    {
                        _name = string.Concat(_name, _middleName.Substring(0, 1), ".");
                    }

                    _name = string.Concat(_name, " ", _lastName);
                }
            }
        }
        #endregion

        #region Properties
        [SQLParameter(ColumnName = "FIRSTNAME", SQLDoWhat = SQLDoWhatEnum.Get)]
        [SQLParameter(ParameterName = "@FIRSTNAME", SQLDoWhat = SQLDoWhatEnum.Create, StoredProcedure = StoredProcedures.USP_CONSTITUENT_CREATE)]
        public string FirstName
        {
            get
            {
                return _firstName;
            }
            set
            {
                _firstName = value;
            }
        }

        [SQLParameter(ColumnName = "MIDDLENAME", SQLDoWhat = SQLDoWhatEnum.Get)]
        [SQLParameter(ParameterName = "@MIDDLENAME", SQLDoWhat = SQLDoWhatEnum.Create, StoredProcedure = StoredProcedures.USP_CONSTITUENT_CREATE)]
        public string MiddleName
        {
            get
            {
                return _middleName;
            }
            set
            {
                _middleName = value;
            }
        }

        [SQLParameter(ColumnName = "LASTNAME", SQLDoWhat = SQLDoWhatEnum.Get)]
        [SQLParameter(ParameterName = "@LASTNAME", SQLDoWhat = SQLDoWhatEnum.Create, StoredProcedure = StoredProcedures.USP_CONSTITUENT_CREATE)]
        public string LastName
        {
            get
            {
                return _lastName;
            }
            set
            {
                _lastName = value;
            }
        }

        [SQLParameter(ParameterName = "@LASTNAMEPREFIX", SQLDoWhat = SQLDoWhatEnum.Create, StoredProcedure = StoredProcedures.USP_CONSTITUENT_CREATE)]
        public string LastNamePrefix
        {
            get
            {
                if (null == _lastNamePrefix)
                {
                    _lastNamePrefix = string.Empty;
                }

                return _lastNamePrefix;
            }
            set
            {
                _lastNamePrefix = value;
            }
        }

        public string Name
        {
            get
            {
                CreateName();
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        [SQLParameter(ParameterName = "@ISORGANIZATION", SQLDoWhat = SQLDoWhatEnum.Create, StoredProcedure = StoredProcedures.USP_CONSTITUENT_CREATE)]
        public bool IsOrganization
        {
            get
            {
                return _isOrganization;
            }
            set
            {
                _isOrganization = value;
            }
        }

        [SQLParameter(ParameterName = "@ISPRIMARY", SQLDoWhat = SQLDoWhatEnum.Create, StoredProcedure = StoredProcedures.USP_CONSTITUENT_CREATE)]
        public bool IsPrimary
        {
            get
            {
                return _isPrimary;
            }
            set
            {
                _isPrimary = value;
            }
        }

        public bool IsActive
        {
            get
            {
                return _isActive;
            }
            set
            {
                _isActive = value;
            }
        }

        public Guid PrimaryID
        {
            get
            {
                return _primaryID;
            }
            set
            {
                _primaryID = value;
            }
        }

        public Address Address
        {
            get
            {
                try
                {
                    if (null == _address)
                    {
                        if (0 < _addresses.Count)
                        {
                            _address = _addresses[0];
                        }
                    }
                }
                catch (NullReferenceException)
                {
                    _address = null;
                }

                return _address;
            }
            set
            {
                _address = value;

                if (null == _addresses)
                {
                    _addresses = new List<Address>();
                }

                _addresses.Add(value);
            }
        }

        public List<Address> Addresses
        {
            get
            {
                return _addresses;
            }
            set
            {
                _addresses = value;
            }
        }

        public Email EmailAddress
        {
            get
            {
                try
                {
                    if (null == _emailAddress)
                    {
                        if (0 < _emailAddresses.Count)
                        {
                            _emailAddress = _emailAddresses[0];
                        }
                    }
                }
                catch (NullReferenceException)
                {
                    _emailAddress = null;
                }

                return _emailAddress;
            }
            set
            {
                _emailAddress = value;

                if (null == _emailAddresses)
                {
                    _emailAddresses = new List<Email>();
                }

                _emailAddresses.Add(value);
            }
        }

        public List<Email> EmailAddresses
        {
            get
            {
                return _emailAddresses;
            }
            set
            {
                _emailAddresses = value;
            }
        }

        public Phone Phone
        {
            get
            {
                try
                {
                    if (null == _phone)
                    {
                        if (0 < _phones.Count)
                        {
                            _phone = _phones[0];
                        }
                    }
                }
                catch (NullReferenceException)
                {
                    _phone = null;
                }

                return _phone;
            }
            set
            {
                _phone = value;

                if (null == _phones)
                {
                    _phones = new List<Phone>();
                }

                _phones.Add(value);
            }
        }

        public List<Phone> Phones
        {
            get
            {
                return _phones;
            }
            set
            {
                _phones = value;
            }
        }
        #endregion

        public object SQLParameter { get; set; }
    }
}